#include "stdafx.h"			
#pragma once
//-------------------------------------------------------------------------------------------------
//ImageProps.h  - Encapsulates the Behaviour and Properties of an Image             
//-------------------------------------------------------------------------------------------------
//FreeBSD License
//Copyright 2011 Will Stott All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are
//permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
//THIS SOFTWARE IS PROVIDED BY Will Stott ``AS IS'' AND ANY EXPRESS OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Will Stott OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//The views and conclusions contained in the software and documentation are those of the
//authors and should not be interpreted as representing official policies, either expressed
//or implied, of Will Stott.
//
//----Authors--------------------------------------------------------------------------------------
//created by: will.stott@ucl.ac.uk July 2011
//
//----Comments-------------------------------------------------------------------------------------
//
// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the IMAGEPROCLIB_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// IMAGEPROCLIBAPI functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
//--------------------------------------------------------------------------------------------------

#ifdef IMAGEPROCLIB_EXPORTS
#define IMAGEPROCLIBAPI __declspec(dllexport)
#else
#define IMAGEPROCLIBAPI __declspec(dllimport)
#endif

#include <vector>
#include <string>

#include "TinyXmlLib.h"

#include "ImageType.h"
#include "Boundary.h"
#include "ImagePt.h"
#include "PtShape.h"
#include "ImageProp.h"

struct IMAGEPROCLIBAPI ImageObjectTypeInfo
{
	std::string _ImageObjectTypeName;
	int			_ImageObjectsCreated;
};

class ImageObjectTypeTool;

class IMAGEPROCLIBAPI ImageProps
{
public:
	static const char * const xmlImageObjectSection;  
	static const char * const xmlImageObjectType;
	static const char * const xmlImage;
	static const char * const xmlBrightness;
	static const char * const xmlContrast;
	static const char * const xmlNotes;
	static const int BrightnessMax = 100;					//must be less than 5 figures, see SetBrightness()
	static const char * const BrightnessMid;
	static const int BrightnessMin = -100;
	static const int ContrastMax = 100;						//must be less than 5 figures, see SetContrast()
	static const char * const ContrastMid;
	static const int ContrastMin = -100;
	static const int NotesLengthMax = 500;
	static const int NameLengthMax = 25;					//maximium length of a property name (xml attribute - 

private:
	ImageType		*_pSelImageType;							//type of image
	std::string		 _Brightness;
	std::string		 _Contrast;
	std::string      _Notes;
 	ImageObject		*_pSelImageObject;						//the image object for which drawing actions apply - LButton down, up. mouse move
	std::string		 _DicomRef;								//dicom ref of image for which these properties relate
//#pragma warning(disable:4251)
	std::vector<ImageProp *>   _imageProperties;				//XML defined properties for image - quality, etc
	std::vector<ImageObject *> _imageObjects;					//collection of objects in image
	std::vector<ImageObjectTypeInfo *> _imageObjectsTypeInfo;	//number of image objects of each type created for this image
//#pragma warning(default:4251)

public:
	ImageProps();
	ImageProps::ImageProps(ImageType *pImageType);
	virtual ~ImageProps();

	void		 ResetToDefaults();
	ImageObject *CreateImageObject(ImageObjectType *pImageObjType);
	bool		 DeleteImageObject(ImageObject *pImageObj);
	bool		 DeleteSelImageObject(ImageObjectTypeTool *pSelTool);
	ImageObject *GetNextIncompatibleImageObject(int startIndex, ImageType *pImageType); //called before ImageProps::SetSelImageType() to ensure the user wants to delete image objects before changing image type

	bool		 SetSelImageType(ImageType *pImageType, ImageObjectTypeTool *pSelTool); 
	ImageType *  GetSelImageType() { return _pSelImageType; }
	bool		 SetBrightness(int val); 
	int			 GetBrightnessValue() { return atoi(_Brightness.c_str()); }
	const char * GetBrightnessStr() { return _Brightness.c_str(); }
	bool		 SetContrast(int val);
	int			 GetContrastValue() { return atoi(_Contrast.c_str()); }
	const char * GetContrastStr() { return _Contrast.c_str(); }
	bool		 SetNotes(const char *notes);
	const char * GetNotes() {return _Notes.c_str(); }

	bool		 AddImageObjectTypeInfo(const char * ImageObjectTypeName);
	int			 IncExpertObjsCreated(const char * ImageObjectTypeName); //called only by ImageObject::Create()
	int			 DecExpertObjsCreated(const char * ImageObjectTypeName); //called only by ImageProps::DeleteImageObject()
	bool		 CanCreateExpertImageObject(ImageObjectType *pImageObjectType); 


	bool		SetDicomRef(const char *pDicomRef); 
	const char *GetDicomRef() {  return _DicomRef.c_str(); }

	ImageProp  *CreateImageProperty(const char *xmlPropName, const char *xmlPropValue, ImageTypeProp *pImagePropType);
	ImageProp  *GetImageProperty(const char *Name);
	bool		SetImageProperty(const char *Name, const char *Value); 
	int			GetImagePropertyCnt() { return _imageProperties.size(); }
	ImageProp  *GetImageProperty(int index) { return ((index >= 0) && (index < GetImagePropertyCnt())) ? _imageProperties[index] : '\0'; }

	ImageObject *GetImageObject(ImageObjectType *pImageObjectType, int index) { return (pImageObjectType) ? GetImageObject(pImageObjectType->GetName(), index) : '\0'; }
	ImageObject *GetImageObject(const char *ImageObjectTypeName, int index);
	ImageObject *GetImageObject(int index) { return ((index >= 0) && (index < GetImageObjectCnt())) ? _imageObjects[index] : '\0'; }
	ImageObject *GetFirstImageObject(ImageObjectTypeTool *pSelTool);
	ImageObject *GetImageObject(const char *Name);

	int		GetImageObjectCnt(ImageObjectType *pImageObjectType)  { return (pImageObjectType)  ? GetImageObjectCnt(pImageObjectType->GetName()) : 0; }
	int		GetImageObjectCnt(const char *ImageObjectTypeName);
	int		GetImageObjectCnt() { return _imageObjects.size(); }	

	ImageProp  *GetSelImageObjectProperty(const char *ImageObjectPropertyName);

	const char *GetImageTypeName(TiXmlElement *pImageXml );

	bool	SaveImageObjects(TiXmlElement *pImageXml, ImageObjectType *pImageObjectType);	
	bool	SaveProperties(TiXmlElement *pImageXml);
	bool	LoadImageObject(TiXmlElement *pImageObjectXml, ImageObjectType *pImageObjectType);
	bool	LoadProperties(TiXmlElement *pImageXml, ImageType *pImageType, ImageObjectTypeTool *pSelTool);

	bool	DeleteNextEmptyImageObjectXml(TiXmlElement *pImageXml);

	ImageObject *GetSelImageObject() { return _pSelImageObject; }
	bool		 SetSelImageObject(ImageObject *pSelImageObject);

static	bool	IsValidDicomRef(const char *dicomRef) { return ((dicomRef != '\0') && (strlen(dicomRef) > 1 )) ? true : false; }
	bool	IsValidSelectedImage() { return ImageProps::IsValidDicomRef(_DicomRef.c_str()); }

private:
	bool		  HasProperty(const char *Name);
	int			  GetIndexForInfoAboutImageObjectsCreatedOfType(const char * imageObjectTypeName);
	bool		  ClearAllImageProperties();
	bool		  ClearAllImagePropertiesNotForSelectedType();
	bool		  ClearAllImageObjects();
	bool		  ClearAllImageObjectsTypeInfo();


};




//-------------------------------------------------------------------------------------------------
//			E N D   O F   F I L E
//-------------------------------------------------------------------------------------------------

